﻿using System;
using System.Collections.Generic;
using Game.Lib;

namespace Game.Lib
{
    public class LandTriangle : Serializable
    {
        /// <summary>
        /// List of points used to define this triangle
        /// </summary>
        public List<Vector2> Points;
        
        /// <summary>
        /// Index into Points of A
        /// </summary>
        public int P0;
        
        /// <summary>
        /// Index into Points of B
        /// </summary>
        public int P1;
        
        /// <summary>
        /// Index into Points of C
        /// </summary>
        public int P2;

        /// <summary>
        /// Returns the area of the land triangle
        /// </summary>
        public float Area
        {
            get
            {
                Vector2 origin = Points[P0];
                return (float)(0.5 * Math.Abs((Points[P1] - origin) % (Points[P2] - origin)));
            }
        }

        /// <summary>
        /// Returns the center of the land triangle
        /// </summary>
        public Vector2 Center
        {
            get
            {
                return Points[P0] + Points[P1] + Points[P2] / 3f;
            }
        }
        
        /// <summary>
        /// The A point of the triangle
        /// </summary>
        public Vector2 A
        {
            get
            {
                return Points[P0];
            }
            set
            {
                P0 = Points.FindIndex(x => x.Equals(value));
                if(P0 == -1)
                {
                    Points.Add(value);
                    P0 = Points.Count - 1;
                }
            }
        }
        
        /// <summary>
        /// The B point of the triangle
        /// </summary>
        public Vector2 B
        {
            get
            {
                return Points[P1];
            }
            set
            {
                P1 = Points.FindIndex(x => x.Equals(value));
                if(P1 == -1)
                {
                    Points.Add(value);
                    P1 = Points.Count - 1;
                }
            }
        }
        
        /// <summary>
        /// The C point of the triangle
        /// </summary>
        public Vector2 C
        {
            get
            {
                return Points[P2];
            }
            set
            {
                P2 = Points.FindIndex(x => x.Equals(value));
                if(P2 == -1)
                {
                    Points.Add(value);
                    P2 = Points.Count - 1;
                }
            }
        }
        
        public LandTriangle()
        {
            Points = new List<Vector2>();
            Points.Add(new Vector2());
            P0 = P1 = P2 = 0;
        }
        
        public LandTriangle(List<Vector2> pts, int p0, int p1, int p2)
        {
            Points = pts;
            P0 = p0;
            P1 = p1;
            P2 = p2;
        }
        
        public LandTriangle(Vector2 a, Vector2 b, Vector2 c, List<Vector2> points)
        {
            Points = points;
            P0 = Points.FindIndex(x => x.Equals(a));
            if(P0 == -1)
            {
                Points.Add(a);
                P0 = Points.Count - 1;
            }
            
            P1 = Points.FindIndex(x => x.Equals(b));
            if(P1 == -1)
            {
                Points.Add(b);
                P1 = Points.Count - 1;
            }
            
            P2 = Points.FindIndex(x => x.Equals(c));
            if(P2 == -1)
            {
                Points.Add(c);
                P2 = Points.Count - 1;
            }
        }
        
        public void UpdateIndices(List<Vector2> points)
        {
            LandTriangle update = new LandTriangle(Points[P0], Points[P1], Points[P2], points);
            Points = update.Points;
            P0 = update.P0;
            P1 = update.P1;
            P2 = update.P2;
        }
        
        public override bool Equals(object o)
        {
            if(!(o is LandTriangle)) return false;
            LandTriangle lt = (LandTriangle)o;
            return  lt.Points == this.Points &&
                    lt.P0 == this.P0 &&
                    lt.P1 == this.P1 &&
                    lt.P2 == this.P2;
        }

        public override int GetHashCode()
        {
            return P0 ^ P1 ^ P2 ^ Points.GetHashCode();
        }

        public void FromBytes(byte[] data, int pos)
        {
            throw new NotImplementedException();
        }

        public byte[] ToBytes()
        {
            throw new NotImplementedException();
        }

        public void Serialize(System.IO.Stream s)
        {
            throw new NotImplementedException();
        }

        public void Deserialize(System.IO.Stream s)
        {
            throw new NotImplementedException();
        }
    }
}